package com.kancy.publicapi.service.impl;

import com.kancy.publicapi.common.util.DebugUtil;
import com.kancy.publicapi.common.util.IPUtils;
import com.kancy.publicapi.common.util.SpringUtils;
import com.kancy.publicapi.service.CommonService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @author kancy
 * @date 2019/12/23 0:46
 **/
@Slf4j
@RequiredArgsConstructor
@Service
public class CommonServiceImpl implements CommonService {
    private final ServerProperties serverProperties;
    /**
     * 查询url
     *
     * @return
     */
    @Override
    public List<String> listUrls() {
        List<String> urls = new ArrayList();
        getUrlDS().forEach(beanName ->{
            Object bean = SpringUtils.getContext().getBean(beanName);
            Class<?> targetClass = AopUtils.getTargetClass(bean);
            Method[] declaredMethods = targetClass.getDeclaredMethods();
            Arrays.stream(declaredMethods).forEach(method -> {
                if (method.isAnnotationPresent(RequestMapping.class)){
                    RequestMapping annotation = method.getAnnotation(RequestMapping.class);
                    if (annotation.value().length > 0) {
                        urls.add(getOneUrl(annotation.value()));
                    }
                }
                if (method.isAnnotationPresent(GetMapping.class)){
                    GetMapping annotation = method.getAnnotation(GetMapping.class);
                    if (annotation.value().length > 0) {
                        urls.add(getOneUrl(annotation.value()));
                    }
                }
                if (method.isAnnotationPresent(PostMapping.class)){
                    PostMapping annotation = method.getAnnotation(PostMapping.class);
                    if (annotation.value().length > 0) {
                        urls.add(getOneUrl(annotation.value()));
                    }
                }
            });
        });
        return urls;
    }

    private String getOneUrl(String[] value) {
        String baseUrl = String.format("http://%s:%s%s", IPUtils.getIp(), serverProperties.getPort(), serverProperties.getServlet().getContextPath());
        return String.format("%s%s",baseUrl, value[ThreadLocalRandom.current().nextInt(0, value.length)]);
    }

    private List<String> getUrlDS() {
        List<String> list = new ArrayList();
        String[] ds1 = SpringUtils.getContext().getBeanNamesForAnnotation(RestController.class);
        String[] ds2 = SpringUtils.getContext().getBeanNamesForAnnotation(Controller.class);
        list.addAll(Arrays.asList(ds1));
        list.addAll(Arrays.asList(ds2));
        return list;
    }
}
